package com.lanyou.esb.cook.proxy.auth.processor.impl;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lanyou.esb.cook.proxy.auth.processor.AcquireAuthProcessor;
import com.lanyou.esb.cook.proxy.common.Constants;
import com.lanyou.esb.cook.proxy.common.SystemResCode;
import com.lanyou.esb.cook.proxy.exception.AuthException;
import com.lanyou.esb.cook.proxy.meta.AuthType;
import com.lanyou.esb.cook.proxy.meta.IfType;
import com.lanyou.esb.cook.proxy.service.impl.TraceLogServiceImpl;

/**
 * HTTP请求类型，默认获取校验信息处理器<br>
 * 
 * 描述:<br>
 * 请求方系统编码，密钥，访问令牌放在请求头里<br>
 * 請求頭名：EsbHead<br>
 * 請求頭值：{"CallSystemCode": "请求方系统编码","ApplyKey": "密钥","AccessToken": "访问令牌"}<br>
 * 例如：<br>
 * EsbHead={"CallSystemCode": "请求方系统编码","ApplyKey": "密钥","AccessToken":
 * "访问令牌"}<br>
 * 
 * 
 * @author Davey.wu
 */
public class DefaultAcquireAuthProcessor implements AcquireAuthProcessor {

	@Override
	public AuthType getAuthType() {
		// 本处理器适用于 HTTP BASIC KEY认证类型
		return AuthType.HTTP_BASIC_KEY;
	}

	@Override
	public IfType getIfType() {
		// 本处理器适用于REST接口
		return IfType.REST;
	}

	@Override
	public Map<String, Object> acquire(HttpServletRequest request,
			String content, Map<String, Boolean> parameters)
			throws AuthException {
		if (parameters == null || parameters.size() == 0) {
			return new HashMap<String, Object>(0);
		}
		// 从请求头获取校验信息
		String info = request.getHeader(Constants.PROXY_HEADER);
		if (StringUtils.isBlank(info)) {
			if (TraceLogServiceImpl.isTrace()) {
				// 记录跟踪日志
				TraceLogServiceImpl.addTraceLog(
						SystemResCode.MSG_AUTHINFO_EMPTY,
						Constants.FLAG_LEFT_SQUARE_BRACKET,
						Constants.MSG_MISS_REQ_HEADER, Constants.FLAG_COLON,
						Constants.PROXY_HEADER,
						Constants.FLAG_RIGHT_SQUARE_BRACKET);
			}
			// 找不到认证信息
			throw new AuthException(SystemResCode.MSG_AUTHINFO_EMPTY,
					SystemResCode.CODE_AUTHINFO_EMPTY);
		}
		ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> mapInfo = null;
		try {
			// 读取JSON格式的核验信息，并将其转换成MAP类型
			mapInfo = mapper.readValue(info, Map.class);
		} catch (Exception e) {
			if (TraceLogServiceImpl.isTrace()) {
				// 记录跟踪日志
				TraceLogServiceImpl.addTraceLog(e.getMessage());
			}
			// 认证信息格式不正确
			throw new AuthException(SystemResCode.MSG_AUTHINFO_FORMATE_ERROR,
					SystemResCode.CODE_AUTHINFO_FORMATE_ERROR);
		}
		// 参数名
		String paraName = "";
		// 参数值
		String paraValue = "";
		// 是否必需
		boolean isAquired = false;
		Map<String, Object> map = new HashMap<>(3);
		for (Map.Entry<String, Boolean> entry : parameters.entrySet()) {
			paraName = entry.getKey();
			isAquired = entry.getValue();
			// 根据参数名获取参数值
			paraValue = ((String) mapInfo.get(paraName)).trim();
			// 参数符合条件，加入结果集中
			if (!isAquired || StringUtils.isNotBlank(paraValue)) {
				map.put(paraName, paraValue);
				continue;
			}
			// 缺少参数为必需，抛出异常 start==============================
			// 缺少访问令牌
			if (Constants.ACCESS_TOKEN.equals(paraName)) {
				// 记录跟踪日志
				if (TraceLogServiceImpl.isTrace()) {
					TraceLogServiceImpl.addTraceLog(
							SystemResCode.MSG_ACCESSTOKEN_EMPTY,
							Constants.FLAG_LEFT_SQUARE_BRACKET, paraName,
							Constants.FLAG_EQUAL, paraValue,
							Constants.FLAG_RIGHT_SQUARE_BRACKET);
				}
				throw new AuthException(SystemResCode.MSG_ACCESSTOKEN_EMPTY,
						SystemResCode.CODE_ACCESSTOKEN_EMPTY);
			}
			// 缺少密钥
			if (Constants.APPLY_KEY.equals(paraName)) {
				// 记录跟踪日志
				if (TraceLogServiceImpl.isTrace()) {
					TraceLogServiceImpl.addTraceLog(
							SystemResCode.MSG_APPLYKEY_EMPTY,
							Constants.FLAG_LEFT_SQUARE_BRACKET, paraName,
							Constants.FLAG_EQUAL, paraValue,
							Constants.FLAG_RIGHT_SQUARE_BRACKET);
				}
				throw new AuthException(SystemResCode.MSG_APPLYKEY_EMPTY,
						SystemResCode.CODE_APPLYKEY_EMPTY);
			}
			// 缺少调用方系统编码
			if (Constants.CALL_SYSTEM_CODE.equals(paraName)) {
				// 记录跟踪日志
				if (TraceLogServiceImpl.isTrace()) {
					TraceLogServiceImpl.addTraceLog(
							SystemResCode.MSG_CALL_SYSTEM_EMPTY,
							Constants.FLAG_LEFT_SQUARE_BRACKET, paraName,
							Constants.FLAG_EQUAL, paraValue,
							Constants.FLAG_RIGHT_SQUARE_BRACKET);
				}
				throw new AuthException(SystemResCode.MSG_CALL_SYSTEM_EMPTY,
						SystemResCode.CODE_CALL_SYSTEM_EMPTY);
			}
			// 其它必需参数缺失,记录跟踪日志
			if (TraceLogServiceImpl.isTrace()) {
				TraceLogServiceImpl.addTraceLog(paraName,
						Constants.MSG_IS_EMPTY,
						Constants.FLAG_LEFT_SQUARE_BRACKET, paraName,
						Constants.FLAG_EQUAL, paraValue,
						Constants.FLAG_RIGHT_SQUARE_BRACKET);
			}
			throw new AuthException(paraName + Constants.MSG_IS_EMPTY, "0");
			// 缺少参数为必需，抛出异常 end==============================
		}
		return map;
	}
}
